package io.netty.groupchat;

import io.netty.ServerHandler;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.timeout.ReadTimeoutHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;

/**
 * Netty 群聊客户端
 *
 * @author Verlet
 * @date 2023-02-05 00:35
 */
@Slf4j
public class GroupChatClient {

    private final int port;
    private final String hostname;

    public GroupChatClient(String hostname, int port) {
        this.hostname = hostname;
        this.port = port;
    }

    public void run() throws InterruptedException {
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(workerGroup).channel(NioSocketChannel.class)
                    .handler(new LoggingHandler(LogLevel.INFO))
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline()
                                    // 设置字符串形式的解码
                                    .addLast(new StringDecoder())
                                    // 设置字符串形式的编码
                                    .addLast(new StringEncoder())
                                    .addLast(new GroupChatClinetHandler());
                        }
                    }).option(ChannelOption.SO_KEEPALIVE, true);

            InetSocketAddress inetSocketAddress = new InetSocketAddress(hostname, port);
            ChannelFuture channelFuture = bootstrap.connect(inetSocketAddress).sync();
            Channel channel = channelFuture.channel();
            log.info("[ {} ] 客户端启动成功。。。",channel.localAddress());
            new Thread(() -> sendMessage(channel)).start();
            channelFuture.channel().closeFuture().sync();

        } finally {
            workerGroup.shutdownGracefully();
        }
    }

    private void sendMessage(Channel channel) {
        try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in))) {
            System.out.print(">> ");
            String msg;
            while (StringUtils.isNotBlank(msg = bufferedReader.readLine())) {
                channel.writeAndFlush(msg);
                System.out.print(">> ");
            }
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        log.info("==========欢迎使用群聊系统V2.0，本系统支持单聊功能(@127.0.0.1:port msg)==========");
        new GroupChatClient("127.0.0.1", GroupChatServer.DEFAULT_PORT).run();
    }
}
